package com.wangwenjun.concurrency.chapter17;


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * 3个线程轮流打印123各10次,使用ReentrantLock
 *
 * 多生产者和多消费者这样的模式必须使用while,因为可能出现虚假唤醒!!!
 *
 */
public class TaoBaoTest13 {

    private static int flag = 1;

    public static void main(String[] args) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Condition condition3 = lock.newCondition();


        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while (flag !=3){
                    try {
                        condition3.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("3");
                flag = 1;
                condition1.signal();
                lock.unlock();
            }
        }, "t3-a").start();

        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while(flag !=3){
                    try {
                        condition3.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("3");
                flag = 1;
                condition1.signal();
                lock.unlock();
            }
        }, "t3-b").start();


        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while(flag !=2){
                    try {
                        condition2.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("2");
                flag = 3;
                condition3.signal();
                lock.unlock();
            }
        }, "t2-a").start();

        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while(flag !=2){
                    try {
                        condition2.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("2");
                flag = 3;
                condition3.signal();
                lock.unlock();
            }
        }, "t2-b").start();



        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while(flag !=1){
                    try {
                        condition1.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("1");
                flag = 2;
                condition2.signal();
                lock.unlock();
            }
        }, "t1-a").start();

        new Thread(()->{
            for (int i = 1; i <= 1000 ; i++) {
                lock.lock();
                while(flag !=1){
                    try {
                        condition1.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("1");
                flag = 2;
                condition2.signal();
                lock.unlock();
            }
        }, "t1-b").start();





    }









}
